using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Data;
using System.Data.SqlClient;
using System.Drawing.Imaging;
using System.Diagnostics;
namespace Repo {
	class DateReport {
		//expects 3 columns: KEY(VERTICAL),DATE(char(16)),QTY
		Font fnt(int size) { return new Font("vardana",size); }
		Pen gridCl(int transp) { return new Pen(transCl(transp)); }
		Color transCl(int transp) { return Color.FromArgb(transp,Color.Black); }
		Brush fntBr(int transp) { return new SolidBrush(transCl(transp)); }
		//public string Create(string title) {
		//  return Create(title,20);
		//}
		public string Create(string title,int singleHight) {
			int bottomMargin=10;
			int leftMargin=30;
			int height=dict.Count*singleHight;

			//foreach(KeyValuePair<string,PointsData> kv in dict)
			//{
			//if(kv.Value.maxX>max) max=kv.Value.maxX;
			//if(kv.Value.minX<min) min=kv.Value.minX;
			//}

			string filename=DateTime.Now.ToString("yyyyMMddHHmmss")+".png";
			int Y=singleHight;
			using(Bitmap bmp=new Bitmap(width+leftMargin*2,height+bottomMargin))
			using(Graphics g=Graphics.FromImage(bmp))
			{
				//g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
				//g.CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceOver;
				g.Clear(Color.White);
				Font f7=fnt(7);
				if(TimeLen==16)
				{
					int startVGrid=(int)(minDate.Date-minDate).TotalMinutes;
					minDate=minDate.Date;
					while((startVGrid+=60)<(width+leftMargin))//vertical
					{
						minDate=minDate.AddHours(1);
						g.DrawLine(gridCl(20),startVGrid+leftMargin,0,startVGrid+leftMargin,height+Y);
						g.DrawString(minDate.ToString("MM-dd HH:00"),f7,Brushes.Black,startVGrid+leftMargin,2);
					}
				}
				else if(TimeLen==19)
				{
					//int startVGrid=(int)Prog.DateToInt(minDate.ToString("yyyy-MM-dd HH:mm:00"))-min;

					int startVGrid=(int)(minDate.Date-minDate).TotalSeconds;

					minDate=minDate.Date;
					while((startVGrid+=60)<(width+leftMargin))//vartical
					{
						minDate=minDate.AddMinutes(1);
						g.DrawLine(gridCl(20),startVGrid+leftMargin,0,startVGrid+leftMargin,height+Y);
						g.DrawString(minDate.ToString("MM-dd HH:mm"),f7,Brushes.Black,startVGrid+leftMargin,2);
					}
				}
				else if(TimeLen==10)
				{
					//int startVGrid=(int)Prog.DateToInt(minDate.ToString("yyyy-MM-dd HH:mm:00"))-min;

					int startVGrid=(int)(minDate.Date-minDate).TotalDays;

					minDate=minDate.Date;
					//while((startVGrid+=60)<(width+leftMargin))//vartical
					//{
					//  minDate=minDate.AddMinutes(1);
					//  g.DrawLine(gridCl(20),startVGrid+leftMargin,0,startVGrid+leftMargin,height+Y);
					//  g.DrawString(minDate.ToString("MM-dd HH:mm"),f7,Brushes.Black,startVGrid+leftMargin,2);
					//}
				}
				foreach(KeyValuePair<string,PointsData> kv in dict)
				{
					//int hash2=(kv.Key??"X")[0].GetHashCode();
					//Color pcol=Color.FromArgb(hash1%hash2);
					int hash1=kv.Key.GetHashCode();
					Color pcol=Color.FromArgb(hash1*5711);
					//if(pcol.A<100)
					pcol=Color.FromArgb(130,pcol.R,pcol.G,pcol.B);
					Pen pen=new Pen(pcol);
					g.DrawLine(gridCl(10),leftMargin,Y-5,leftMargin*2+width,Y-5);//horizontal 5
					g.DrawString(kv.Key,fnt(8),Brushes.Black,2,Y-11);
					for(int x=leftMargin+40;x<bmp.Width;x+=120)//hints across
						g.DrawString(kv.Key,fnt(7),fntBr(18),x,Y-11);
					foreach(Point p in kv.Value.dateVals)
					{
						int X=p.X+leftMargin;
						//g.DrawLine(pen,X,Y-p.Y,X,Y);
						g.DrawLine(new Pen(Color.FromArgb(Math.Max(40,180-p.Y),pcol)),X,Y-p.Y,X,Y);
						//try
						//{
						bmp.SetPixel(X,Y,Color.Black);
						bmp.SetPixel(X,Math.Max(Y-p.Y,0),Color.Black);
						//}
						//catch
						//{
						//  continue;
						//}
					}
					g.DrawLine(gridCl(30),0,Y,leftMargin*3+width,Y);//horizontal 0
					Y+=singleHight;
				}
				Font f12=fnt(10);
				//title left-top corner
				title+=DateTime.Now.ToString(" (yyyy-MM-dd HH:mm:ss)");
				Size siz=g.MeasureString(title,f12).ToSize();
				Point pnt=new Point(10,14);
				Rectangle rect=new Rectangle(pnt,siz);
				rect.Inflate(0,1);
				g.FillRectangle(new SolidBrush(Color.FromArgb(80,Color.LightYellow)),rect);
				g.DrawRectangle(Pens.Gray,rect);
				g.DrawString(title,f12,Brushes.Black,pnt);
				bmp.Save(@"C:\img\graph\"+filename,ImageFormat.Png);
			}
			return filename;
			//Process.Start(filename);

		}

		DateTime minDate;
		DateTime maxDate;
		int TimeLen=0;
		int width;

		public DateReport(DataTable data) {
			dict=new Dictionary<string,PointsData>();
			if(data.Rows.Count<2)
			{
				throw new Exception("no data");
				//return;
			}
			TimeLen=data.Rows[0][1].ToString().Length;
			string colDate=data.Columns[1].Caption;
			//s obj1=data.Compute(string.Format("min({0})",colDate),"");
			//object obj2=data.Compute("max(Column2)","");


			minDate=DateTime.ParseExact(data.Compute(string.Format("min({0})",colDate),"").ToString(),"yyyy-MM-dd HH:mm:ss".Substring(0,TimeLen),null);
			maxDate=DateTime.ParseExact(data.Compute(string.Format("max({0})",colDate),"").ToString(),"yyyy-MM-dd HH:mm:ss".Substring(0,TimeLen),null);
			if(TimeLen==16)
			{
				width=(int)(maxDate-minDate).TotalMinutes;
				foreach(DataRow row in data.Rows)
				{
					string key=row[0].ToString();
					DateTime dt=DateTime.ParseExact(row[1].ToString(),"yyyy-MM-dd HH:mm:ss".Substring(0,TimeLen),null);
					//if(dt<minDate) minDate=dt;
					//int x=(int)Prog.DateToInt(row[1].ToString());

					int x=(int)(dt-minDate).TotalMinutes;
					int val=(int)row[2];
					if(!dict.ContainsKey(key))
						dict.Add(key,new PointsData());
					dict[key].Add(x,val);
				}
			}
			else if(TimeLen==19)
			{
				width=(int)(maxDate-minDate).TotalSeconds;
				foreach(DataRow row in data.Rows)
				{
					string key=row[0].ToString();
					DateTime dt=DateTime.ParseExact(row[1].ToString(),"yyyy-MM-dd HH:mm:ss".Substring(0,TimeLen),null);
					//if(dt<minDate) minDate=dt;
					//int x=(int)Prog.DateToInt(row[1].ToString());

					int x=(int)(dt-minDate).TotalSeconds;
					int val=(int)row[2];
					if(!dict.ContainsKey(key))
						dict.Add(key,new PointsData());
					dict[key].Add(x,val);
				}



			}
			else if(TimeLen==10)
			{
				width=(int)(maxDate-minDate).TotalDays;
				foreach(DataRow row in data.Rows)
				{
					string key=row[0].ToString();
					DateTime dt=DateTime.ParseExact(row[1].ToString(),"yyyy-MM-dd HH:mm:ss".Substring(0,TimeLen),null);
					//if(dt<minDate) minDate=dt;
					//int x=(int)Prog.DateToInt(row[1].ToString());

					int x=(int)(dt-minDate).TotalDays;
					int val=(int)row[2];
					if(!dict.ContainsKey(key))
						dict.Add(key,new PointsData());
					dict[key].Add(x,val);
				}



			}
		}
		Dictionary<string,PointsData> dict;
	}
	class PointsData {
		//public int maxX=0;
		//int sumVal=0;
		//public int minX=int.MaxValue;
		//public int maxVal=0;
		public List<Point> dateVals=new List<Point>();
		public void Add(int x,int val) {
			dateVals.Add(new Point(x,val));
			//if(x>maxX) maxX=x;
			//if(x<minX) minX=x;
			//if(val>maxVal) maxVal=val;
			//sumVal+=val;
		}
		//public IEnumerable<Point> Points(int globalMinX)
		//{
		//  foreach(Point p in dateVals)
		//    yield return new Point(p.X-globalMinX,p.Y);
		//}
	}
}
